import fileApi from '@/api/file'
import { apiDefaultErrorHandler } from '@/api/base'
import { warning } from '@/utils/message'

/**
 * 是否包含指定class
 * @param {HTMLElement} ele
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass (ele, cls) {
  return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
}

/**
 * 添加class
 * @param {HTMLElement} ele
 * @param {string} cls
 */
export function addClass (ele, cls) {
  if (!hasClass(ele, cls)) ele.className += ' ' + cls
}

/**
 * 删除class
 * @param {HTMLElement} ele
 * @param {string} cls
 */
export function removeClass (ele, cls) {
  if (hasClass(ele, cls)) {
    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
    ele.className = ele.className.replace(reg, ' ')
  }
}

/**
 * 获取uuid
 */
export function getUUID () {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
    return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
  })
}

/**
 * 是否有权限
 * @param {*} key
 */
export function isAuth (key) {
  return JSON.parse(sessionStorage.getItem('permissions') || '[]').indexOf(key) !== -1 || false
}

/**
 * 树形数据转换
 * @param {*} data
 * @param {*} id
 * @param {*} pid
 */
export function treeDataTranslate (data, id = 'id', pid = 'parentId') {
  let res = []
  let temp = {}
  for (let i = 0; i < data.length; i++) {
    temp[data[i][id]] = data[i]
  }
  for (let k = 0; k < data.length; k++) {
    if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) {
      if (!temp[data[k][pid]]['children']) {
        temp[data[k][pid]]['children'] = []
      }
      if (!temp[data[k][pid]]['_level']) {
        temp[data[k][pid]]['_level'] = 1
      }
      data[k]['_level'] = temp[data[k][pid]]._level + 1
      temp[data[k][pid]]['children'].push(data[k])
    } else {
      res.push(data[k])
    }
  }
  return res
}

/**
 * 是否是json字符串
 * @param str
 * @returns {boolean}
 */
export function isJSONString (str) {
  try {
    if (typeof JSON.parse(str) === 'object') {
      return true
    }
  } catch (ex) {
    // console.log('不是json字符串')
  }
  return false
}

/**
 * array是否包含array2
 * @param array
 * @param array2
 */
export function containsAll (array, array2) {
  if (!(array instanceof Array) || !(array2 instanceof Array)) return false
  if (array.length < array2.length) return false
  let arrayStr = array.toString()
  for (let i = 0; i < array2.length; i++) {
    if (arrayStr.indexOf(array2[i]) === -1) return false
  }
  return true
}

/**
 * 后台错误提示信息中的占位符处理
 * 检查字符串中是否有占位符 没有则返回原数据
 * 例如：msg = '第{0}行第{1}列数据类型错误' 返回true
 * msg格式必须是第一个逗号前是所有提示信息（提示信息中不可使用半角逗号，若需要使用逗号请使用全角逗号）
 * 第一个逗号后为模板值，用半角逗号分隔
 * 例如：msg = '第{0}行第{1}列数据类型错误,1,2'
 * 返回：'第1行第2列数据类型错误'
 * @param langMsg 多语言处理过的msg
 * @param msg 后台返回的msg
 * @returns {string}
 */
export function handlePlaceholder (langMsg, msg) {
  if (!(msg.indexOf('{') > -1) && (msg.indexOf('}') > -1)) {
    return msg
  }
  let msgArray = msg.split(',')
  msgArray.splice(0, 1)
  for (let i = 0; i < msgArray.length; i++) {
    langMsg = langMsg.replace(new RegExp('\\{' + i + '\\}', 'g'), msgArray[i])
  }
  return langMsg
}

/**
 * 信息弹窗标题
 * @param operation{string}
 * @returns {string}
 */
export function titleHandle (operation) {
  if (operation === 'add') {
    return '新增'
  } else if (operation === 'update') {
    return '修改'
  } else if (operation === 'view') {
    return '查看'
  } else {
    return ''
  }
}

/**
 * 处理查看时disabled属性
 * @param operation
 * @returns {boolean}
 */
export function disabledHandle (operation) {
  return operation === 'info' || operation === 'verify';
}

/**
 * 检验项目信息弹窗标题
 * @param itemType{int}
 * @returns {string}
 */
export function checkItemTitleHandle (itemType) {
  if (itemType === 1) {
    return '数值型'
  } else if (itemType === 2) {
    return '单选型'
  } else if (itemType === 3) {
    return '多选型'
  } else if (itemType === 4) {
    return '文本型'
  } else {
    return ''
  }
}

/**
 * 注意：如果存在以下情况，请自行处理
 * 1、如果obj里面有时间对象，则JSON.stringify后再JSON.parse的结果，时间将只是字符串的形式。而不是时间对象；
 * 2、如果obj里有RegExp、Error对象，则序列化的结果将只得到空对象；
 * 3、如果obj里有函数，undefined，则序列化的结果会把函数或 undefined丢失；
 * 4、如果obj里有NaN、Infinity和-Infinity，则序列化的结果会变成null
 * 5、JSON.stringify()只能序列化对象的可枚举的自有属性，例如 如果obj中的对象是有构造函数生成的，则使用JSON.parse(JSON.stringify(obj))深拷贝后，会丢弃对象的constructor；
 * 6、如果对象中存在循环引用的情况也无法正确实现深拷贝；
 * @param obj
 * @returns {any}
 */
export function deepCopy (obj) {
  return JSON.parse(JSON.stringify(obj))
}

/**
 * 判断是否为Array类型
 * @param value
 * @returns {boolean}
 */
export function isArray (value) {
  if (typeof Array.isArray === 'function') {
    return Array.isArray(value)
  } else {
    return Object.prototype.toString.call(value) === '[object Array]'
  }
}

/**
 *  处理下载流
 * @param type 类型
 * @param fileName 文件名
 * @param fileType 文件类型
 */
export function downloadFile (type, fileName, fileType) {
  let params = {
    'type': type,
    'lang': getLanguage()
  }
  fileApi.downloadTemplate(params).then(({ data }) => {
    // 构造一个blob对象来处理数据
    const blob = new Blob([data])
    const name = fileName + '.' + fileType
    // 对于<a>标签，只有 Firefox 和 Chrome（内核） 支持 download 属性
    // IE10以上支持blob但是依然不支持download
    if ('download' in document.createElement('a')) { // 支持a标签download的浏览器
      const link = document.createElement('a')// 创建a标签
      link.download = name// a标签添加属性
      link.style.display = 'none'
      link.href = URL.createObjectURL(blob)
      document.body.appendChild(link)
      link.click()// 执行下载
      URL.revokeObjectURL(link.href) // 释放url
      document.body.removeChild(link)// 释放标签
    } else { // 其他浏览器
      navigator.msSaveBlob(blob, fileName)
    }
  }).catch((ex) => {
    apiDefaultErrorHandler(ex)
  })
}

/**
 * 设置调用选择组件的输入框只读
 */
export function setReadonlyPickInput() {
  let readonlyPickInputList = document.getElementsByClassName('my-readonly-pick-input')
  if (readonlyPickInputList && readonlyPickInputList.length > 0) {
    for (let i = 0; i < readonlyPickInputList.length; i++) {
      let inputElements = readonlyPickInputList[i].getElementsByTagName('input')
      if (inputElements && inputElements.length > 0) {
        inputElements[0].readOnly = true
      }
    }
  }
}

/**
 * 改变日期格式
 * @param date
 * @param fmt
 * @return {*}
 */
export function formatDate (date, fmt) {
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
  }
  let o = {
    'M+': date.getMonth() + 1,
    'd+': date.getDate(),
    'h+': date.getHours(),
    'm+': date.getMinutes(),
    's+': date.getSeconds(),
    'S+': date.getMilliseconds()
  };
  for (let k in o) {
    if (new RegExp(`(${k})`).test(fmt)) {
      let str = o[k] + '';
      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str, RegExp.$1.length));
    }
  }
  return fmt;
}

function padLeftZero (str, num) {
  let zero = ''
  for (let i = 0; i < num; i++) {
    zero = zero + '0'
  }
  return (zero + str).substr(str.length);
}

/**
 * 获取新日期
 * 日期加上天数(默认加一天)
 * @param dateString
 * @param days
 * @returns {string}
 */
export function addDate(dateString, days) {
  if (!dateString) {
    return ''
  }
  if(days === undefined || days === '') {
    days = 1;
  }
  let date = new Date(dateString);
  date.setDate(date.getDate() + days);
  let month = date.getMonth() + 1;
  let day = date.getDate();
  let mm = "'" + month + "'";
  let dd = "'" + day + "'";
  //单位数前面加0
  if(mm.length === 3) {
    month = "0" + month;
  }
  if(dd.length === 3) {
    day = "0" + day;
  }
  return date.getFullYear() + "-" + month + "-" + day;
}

/**
 * 获取当前时间
 * @return {string}
 */
export function currentDate () {
  let date = new Date();

  let month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1; //获取月,如果小于10,前面补个0
  let strDate = date.getDate() < 10 ? '0' + date.getDate() : date.getDate(); //获取日,如果小于10,前面补个0
  let strHours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); //获取小时,如果小于10,前面补个0
  let strMinutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); //获取分,如果小于10,前面补个0
  let strSeconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds(); //获取秒,如果小于10,前面补个0
   //拼接一下
  return date.getFullYear() + month + strDate + strHours + strMinutes + strSeconds;
}

/**
 * 转换文件大小为string显示
 * @param size
 * @return {string}
 */
const FILE_SIZE_UNITS = ['B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
export function  convertFileSizeToString (value) {
  for (let i = 0; i < FILE_SIZE_UNITS.length; i++) {
    if (value < Math.pow(1024, i)) {
      if (FILE_SIZE_UNITS[i - 1]) {
        return (value / Math.pow(1024, i - 1)).toFixed(1) + FILE_SIZE_UNITS[i - 1]
      }
      return value + FILE_SIZE_UNITS[i]
    }
  }
}

/**
 * 文件下载
 * @param fileId
 * @param fileName
 * @param fileType
 */
export function download (fileId, fileName, fileType) {
  fileApi.download({ fileId: fileId }).then(({ data }) => {
    const blob = new Blob([data])
    const name = fileName + '.' + fileType
    if ('download' in document.createElement('a')) { // 支持a标签download的浏览器
      const link = document.createElement('a')// 创建a标签
      link.download = name// a标签添加属性
      link.style.display = 'none'
      link.href = URL.createObjectURL(blob)
      document.body.appendChild(link)
      link.click()// 执行下载
      URL.revokeObjectURL(link.href) // 释放url
      document.body.removeChild(link)// 释放标签
    } else { // 其他浏览器
      navigator.msSaveBlob(blob, fileName)
    }
  }).catch((ex) => {
    apiDefaultErrorHandler(ex)
  })
}

/**
 * 获取elementUI图片选择后本地url
 * @return {string}
 */
export function getElementUILocalPictureUrl (file) {
  if (file && file.url) {
    return file.url
  } else {
    return ''
  }
}

/**
 * 检查项目单选数据结构转换
 * @return {Array}
 */
export function convertCheckItemRadio (list) {
  if (!isArray(list)) {
    return []
  }
  list.forEach(item => {
    item.value = null
    item.content.forEach((content, index) => {
      if (content.value === true) {
        item.value = index
      }
    })
  })
  return list
}

/**
 * 检查项目单选数据结构还原
 * @return {Array}
 */
export function revertCheckItemRadio (list) {
  if (!isArray(list)) {
    return []
  }
  list.forEach(item => {
    item.content.forEach(() => {
      delete item.value
    })
  })
  return list
}

/**
 * 取数组a、b的交集
 * @param a 数组
 * @param b 数组
 * @returns 交集
 */
export function intersection (a, b) {
  return a.filter(function (val) {
    return b.indexOf(val) > -1
  })
}

/**
 * 判断仓库管理模式个数
 * 多个或者没有，则显示为管理编号
 * 一个，物料号（管理编号字段 - 显示物料号）
 * 一个，板位号（管理编号字段 - 显示板位号）
 */
export function isManagementNumber (that) {
  let managementMode = that.$store.getters.storehouseManagementMode
  let arr = managementMode.split(',')
  return !managementMode || arr.length > 1 || arr.length <= 0 // 仓库管理模式有多个或者没有
}

/**
 * 计算两个日期之间的天数
 * @param earlierDate 较早的日期
 * @param laterDate 较晚的日期
 * @returns {number}
 */
export function getDiffDate(earlierDate, laterDate) {
  let date1 = new Date(earlierDate.getFullYear(), earlierDate.getMonth(), earlierDate.getDate());
  let date2 = new Date(laterDate.getFullYear(), laterDate.getMonth(), laterDate.getDate());
  const diff = date2.getTime() - date1.getTime();
  return diff / (24 * 60 * 60 * 1000);
}

/**
 * 导出Excel
 *
 * @param {String} fileName 文件名称
 * @param {Blob} data Blob对象
 */
export function exportExcel (fileName, data) {
  if (data.size > 48) {
    let reader = new FileReader()
    reader.readAsDataURL(data)
    reader.onload = function (e) {
      if ('download' in document.createElement('a')) { // 非IE下载
        let a = document.createElement('a')
        a.download = fileName
        a.href = e.target.result
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
      } else { // IE10+下载
        navigator.msSaveBlob(data, fileName)
      }
    }
  } else {
    warning(i18n.t('apiCodeMsg.NO_DATA_TO_EXPORT'))
  }
}

/**
 * 获取当前日期【day】天前日期
 * 默认获取最近startDay天
 *
 * @param moment
 * @param {int} startDay 天数
 * @return string[]
 */
export function queryDay(moment, startDay) {
  return [
    moment().subtract(startDay, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'),
    moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
  ]
}